package com.exec;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.tycmc.util.RedisUtil;
import com.util.DateUtil;
import com.util.DruidUtil;
import com.util.PropertiesUtil;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
import ty.pub.TransPacket;

import java.text.SimpleDateFormat;
import java.util.*;

public class EngineFltController {
    /**
     * 处理发动机故障
     * @param inputObject
     * @return
     */
    public  static String execEngineFlt(com.tycmc.bean.InputObject inputObject)  {
        //故障工况编号
        String engineFltNumber= PropertiesUtil.getStringPro("EngineFltDutyNumber");
        //信息生成时间编号
        String msgTimeNumber=PropertiesUtil.getStringPro("MsgTimeNumber");
        //key编号
        String EngineFltTemplate=PropertiesUtil.getStringPro("EngineFltTemplate");
        String EngineFlt=PropertiesUtil.getStringPro("EngineFlt");
        //判断inputObject中是否存在这个工况信息
        TransPacket transPacket= inputObject.getTransPacket();
        //获取基础数据
        Map<String,String> baseInfo=transPacket.getBaseInfoMap();
        //获取工况数据
        Map<String,Map<Long,String>>workStatusMap=transPacket.getWorkStatusMap();
        //获取故障工况数据
        Map<Long,String>mapFlt=workStatusMap.get(engineFltNumber);
        //判断是否为空
        if(MapUtils.isNotEmpty(mapFlt)){
            //获取设备ID
            String vclId=transPacket.getDeviceId();
            //去掉设备ID的前缀
            vclId=vclId.substring(4,vclId.length());
            EngineFltTemplate=EngineFltTemplate.replaceAll("VCLID",vclId);
            //获取信息生成时间
            long msgTime=MapUtils.getLong(baseInfo,msgTimeNumber);
            //获取信息生成时间数据集合
            Map<String,Object>mapStatic=inputObject.getCacheMap();
            String theVclmsgTime=MapUtils.getString(mapStatic,vclId+"_"+EngineFlt);
            //将sql存入这里面
            List<String> jsonSql=new ArrayList<String>();
            Map<String,Object>mapLastFlt=new HashMap<String,Object>();
            //如果为空，直接存入缓存map中
            if(StringUtils.isBlank(theVclmsgTime)){
                mapStatic.put(vclId+"_"+EngineFlt,DateUtil.getStrTime(msgTime,0));
                jsonSql.add(" insert into  CacheKZExecTable(CKZET_VclId,CKZET_LastMsgTime,CKZET_InsertTime,CKZET_Type)values('"+vclId+"','"+DateUtil.getStrTime(msgTime,0)+"',now(),"+EngineFlt+")  " +
                        "ON DUPLICATE KEY UPDATE CKZET_LastMsgTime='"+DateUtil.getStrTime(msgTime,0)+"',CKZET_InsertTime=now()");
            }else{//如果不为空
                //上下时间比较
                long lastVclmsgTime=Long.valueOf(DateUtil.getLongTime(theVclmsgTime));
                if(msgTime>=lastVclmsgTime){
                    mapStatic.put(vclId+"_"+EngineFlt,DateUtil.getStrTime(msgTime,0));
                    jsonSql.add(" insert into  CacheKZExecTable(CKZET_VclId,CKZET_LastMsgTime,CKZET_InsertTime,CKZET_Type)values('"+vclId+"','"+DateUtil.getStrTime(msgTime,0)+"',now(),"+EngineFlt+")  " +
                            "ON DUPLICATE KEY UPDATE CKZET_LastMsgTime='"+DateUtil.getStrTime(msgTime,0)+"',CKZET_InsertTime=now()");
                }else{
                    //缓存数据
                    return null;
                }
            }
            //遍历故障集合
            for(long key:mapFlt.keySet()){
                String fltMsgTime=DateUtil.getStrTime(msgTime,key);
                //故障数组字符串
                String JsonFltStr=mapFlt.get(key);
                //将字符串转换为json数组
                JSONArray JsonFltObj=JSONArray.parseArray(JsonFltStr);
                //循环遍历故障集合
                for(Object object:JsonFltObj){
                    JSONObject jsonObject=(JSONObject)object;
                    String Type=MapUtils.getString(jsonObject,"Type");
                    if("1".equals(Type)){
                        jsonObject.put("fltMsgTime",fltMsgTime);
                        jsonObject.put("VehicleId",vclId);
                        String FMI=MapUtils.getString(jsonObject,"FMI");
                        String SPN=MapUtils.getString(jsonObject,"SPN");
                        String OC=MapUtils.getString(jsonObject,"OC");
                        //判断mapLastFlt中是否包含，目的是最新表和redis总仅保留最新的一条状态
                        if(StringUtils.isNotBlank(MapUtils.getString(mapLastFlt,FMI+"_"+SPN))){//存在于集合中，说明此包中此故障存在多条,走更新，插入逻辑
                            JSONObject jsonObject1=(JSONObject)mapLastFlt.get(FMI+"_"+SPN);
                            //判断故障次数是否一致
                            String OC1=MapUtils.getString(jsonObject1,"OC");
                            mapLastFlt.put(FMI+"_"+SPN,jsonObject);//将最新故障存入map中
                            if(OC.equals(OC1)){
                                jsonObject.put("OcIsEquals",true);
                                continue;
                            }
                            jsonObject1.put("releaseTime",fltMsgTime);
                            jsonSql.add(getFltSql(1,jsonObject1));//使用现有map的值进行更新
                            jsonSql.add(getFltSql(2,jsonObject));//使用最新map的值进行插入
                        }else{//Map中不存在,判断redis中是否存在
                            String jsonResidStr= RedisUtil.hget(EngineFltTemplate,FMI+"_"+SPN);
                            if(StringUtils.isNotBlank(jsonResidStr)){//redis存在此故障，走更新，插入逻辑
                                JSONObject jsonResidObj=JSONObject.parseObject(jsonResidStr);
                                String OC1=MapUtils.getString(jsonResidObj,"OC");
                                mapLastFlt.put(FMI+"_"+SPN,jsonObject);//将最新故障存入map中
                                if(OC.equals(OC1)){
                                    jsonObject.put("OcIsEquals",true);
                                    continue;
                                }
                                jsonResidObj.put("VehicleId",vclId);
                                jsonResidObj.put("releaseTime",fltMsgTime);
                                jsonSql.add(getFltSql(1,jsonResidObj));//使用现有map的值进行更新
                                jsonSql.add(getFltSql(2,jsonObject));//使用最新map的值进行插入
                            }else{//redis不存在此故障，执行插入操作
                                mapLastFlt.put(FMI+"_"+SPN,jsonObject);//将最新故障存入map中
                                jsonSql.add(getFltSql(2,jsonObject));//使用最新map的值进行插入
                            }
                        }
                    }else{//暂时没有解除逻辑

                    }
                }
            }
            List<String> fltlastlist=new ArrayList<String>();
            //开始处理现行故障
            if(MapUtils.isNotEmpty(mapLastFlt)){//只有不为空的时候，我们才执行
                Set<String> fltkeyset=RedisUtil.hkeys(EngineFltTemplate);
                Jedis jedis=RedisUtil.getJedis();
                Transaction tx=jedis.multi();//开启事务
                for(String key:fltkeyset){
                    if(!mapLastFlt.containsKey(key)){//本条记录需要更新或插入
                        String redisObjStr=RedisUtil.hget(EngineFltTemplate,key);
                        JSONObject redisJSONObj=JSONObject.parseObject(redisObjStr);
                        //删除
                        tx.hdel(EngineFltTemplate,key);
                        fltlastlist.add("delete from Msg_Flt_Happening where MsgFH_VCLID_FMI_SPN='"+vclId+"_"+key+"'");
                        redisJSONObj.put("releaseTime",DateUtil.getStrTime(msgTime,0));
                        fltlastlist.add(getFltSql(3,redisJSONObj));//使用最新map的值进行插入
                    }
                }
                for(String key:mapLastFlt.keySet()){
                    JSONObject job=(JSONObject)mapLastFlt.get(key);
                    tx.hset(EngineFltTemplate,key,JSONObject.toJSONString(job));
                    String FMI=MapUtils.getString(job,"FMI");
                    String SPN=MapUtils.getString(job,"SPN");
                    String fltMsgTime=MapUtils.getString(job,"fltMsgTime");
                    String VehicleId=MapUtils.getString(job,"VehicleId");
                    String OC=MapUtils.getString(job,"OC");
                    boolean OcIsEquals=MapUtils.getBooleanValue(job,"OcIsEquals");
                    if(!OcIsEquals){//次数不相等的才执行插入操作更新操作
                        fltlastlist.add("Insert into Msg_Flt_Happening(MsgFH_Vcl_ID,MsgFH_FaultSPN,MsgFH_FaultFMI,MsgFH_MsgTime,MsgFH_FaultType,msgfh_oc,MsgFH_VCLID_FMI_SPN)" +
                                "values("+VehicleId+",'"+SPN+"','"+FMI+"','"+fltMsgTime+"',1,"+OC+",'"+VehicleId+"_"+key+"')ON DUPLICATE KEY UPDATE " +
                                "MsgFH_MsgTime='"+fltMsgTime+"',msgfh_oc="+OC);
                    }
                }
                tx.exec();
                jedis.close();
            }
            fltlastlist.addAll(jsonSql);
            if(fltlastlist.size()>0){
                DruidUtil.batch(fltlastlist);
            }
            return null;
        }else{//没有故障，说明全部解除

        }
        return null;
    }

    public static String getFltSql(int type,JSONObject jsonObject){
        String sql="";
        switch (type) {
            case 1://更新故障
                String FMI=MapUtils.getString(jsonObject,"FMI");
                String SPN=MapUtils.getString(jsonObject,"SPN");
                String fltMsgTime=MapUtils.getString(jsonObject,"fltMsgTime");
                String releaseTime=MapUtils.getString(jsonObject,"releaseTime");
                String VehicleId=MapUtils.getString(jsonObject,"VehicleId");
                String OC=MapUtils.getString(jsonObject,"OC");
                sql="update Msg_FaultAlarm_"+fltMsgTime.substring(0,8).replaceAll("-","")+" set MsgFA_State=2 , MsgFA_Release='"+releaseTime+"' " +
                        "where MsgFA_Vcl_ID="+VehicleId+" and MsgFA_FaultFMI='"+FMI+"' and MsgFA_FaultSPN='"+SPN+"' and MsgFA_State=1 and MsgFH_FaultType=1 and MsgFA_OC="+OC;
                break;
            case 2://插入故障
                String _FMI=MapUtils.getString(jsonObject,"FMI");
                String _SPN=MapUtils.getString(jsonObject,"SPN");
                String _fltMsgTime=MapUtils.getString(jsonObject,"fltMsgTime");
                String _VehicleId=MapUtils.getString(jsonObject,"VehicleId");
                String _OC=MapUtils.getString(jsonObject,"OC");
                sql="insert into  Msg_FaultAlarm_"+_fltMsgTime.substring(0,8).replaceAll("-","")+" (MsgFA_Vcl_ID,MsgFA_FaultFMI,MsgFA_FaultSPN," +
                        "MsgFA_MsgTime,MsgFH_FaultType,MsgFA_State,MsgFA_OC)values("+_VehicleId+",'"+_FMI+"','"+_SPN+"','"+_fltMsgTime+"',1,1,"+_OC+")";
                break;
            case 3://更新故障
                String _FMI3=MapUtils.getString(jsonObject,"FMI");
                String _SPN3=MapUtils.getString(jsonObject,"SPN");
                String _fltMsgTime3=MapUtils.getString(jsonObject,"fltMsgTime");
                //解除时间任务是系统时间
                String _releaseTime3= MapUtils.getString(jsonObject,"releaseTime");
                String _VehicleId3=MapUtils.getString(jsonObject,"VehicleId");
                String _OC3=MapUtils.getString(jsonObject,"OC");
                sql="update Msg_FaultAlarm_"+_fltMsgTime3.substring(0,8).replaceAll("-","")+" set MsgFA_State=2 , MsgFA_Release='"+_releaseTime3+"' " +
                        "where MsgFA_Vcl_ID="+_VehicleId3+" and MsgFA_FaultFMI='"+_FMI3+"' and MsgFA_FaultSPN='"+_SPN3+"' and MsgFA_State=1 and MsgFH_FaultType=1 ";
                break;
            default:
                break;
        }
        return sql;
    }
}
